"""
https://blog.csdn.net/saltriver/article/details/79680859
图像“颜色选择”怎么用？
https://blog.csdn.net/saltriver/article/details/79680973
选择图像的“感兴趣区域”
https://blog.csdn.net/saltriver/article/details/80547245
Hough直线检测的理解
"""

import cv2 as cv
import numpy as np
import sys

np.random.seed(1)
imshow_no = 0


def rand_color():
    return (
        np.random.randint(0, 256),
        np.random.randint(0, 256),
        np.random.randint(0, 256),
    )


###############################################################
# load
img_path = '../../../../large_data/pic/lane/lane.jfif'
img = cv.imread(img_path, cv.IMREAD_COLOR)
H, W = img.shape[:2]
print('h, w =', H, W)
imshow_no += 1
cv.imshow(f'{imshow_no} original', img)
img_ = img.copy()
img = cv.cvtColor(img, cv.COLOR_BGR2HSV)

###############################################################
# filter color
lower = (0, 0, 225)
upper = (180, 25, 255)
white_mask = cv.inRange(img, lower, upper)
# imshow_no += 1
# cv.imshow(f'{imshow_no} white_mask', white_mask)

yellow = 22
lower = (yellow - 30, 75, 75)
upper = (yellow + 30, 255, 255)
yellow_mask = cv.inRange(img, lower, upper)
# imshow_no += 1
# cv.imshow(f'{imshow_no} yellow_mask', yellow_mask)

mask = cv.bitwise_or(white_mask, yellow_mask)
# imshow_no += 1
# cv.imshow(f'{imshow_no} mask', mask)

###############################################################
# mask of mask
small_factor = 0.05
large_factor = 0.6
left_top = (W/2 - W * small_factor, H * large_factor)
right_top = (W/2 + W * small_factor, H * large_factor)
left_bottom = (0, H)
right_bottom = (W, H)
pts = np.int32([left_top, right_top, right_bottom, left_bottom])
mask_of_mask = np.zeros_like(mask)
cv.fillPoly(mask_of_mask, [pts], 255)
# imshow_no += 1
# cv.imshow(f'{imshow_no} mask_of_mask', mask_of_mask)

###############################################################
# apply mask of mask
mask = cv.bitwise_and(mask, mask, mask=mask_of_mask)
# imshow_no += 1
# cv.imshow(f'{imshow_no} masked mask', mask)

###############################################################
# canny
mask = cv.GaussianBlur(mask, (5, 5), 0)
# imshow_no += 1
# cv.imshow(f'{imshow_no} blured mask', mask)
canny = cv.Canny(mask, 100, 200)
# imshow_no += 1
# cv.imshow(f'{imshow_no} canny', canny)

###############################################################
# hough lines
threshold = 10
min = 20
max = 50
pts = cv.HoughLinesP(canny, 1, np.pi/180, threshold=threshold, minLineLength=20, maxLineGap=max)
if pts is None:
    print('No straight line.')
    sys.exit(0)

print(np.shape(pts))
cnt = 0
bg = np.zeros_like(img)
for lines in pts:
    for line in lines:
        cnt += 1
        x1, y1, x2, y2 = line
        cv.line(bg, (x1, y1), (x2, y2), rand_color(), 1)
imshow_no += 1
cv.imshow(f'{imshow_no} lines', bg)

###############################################################
# tick them
img = img_
for lines in pts:
    for line in lines:
        cnt += 1
        x1, y1, x2, y2 = line
        cv.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
imshow_no += 1
cv.imshow(f'{imshow_no} result', img)

###############################################################
# final
cv.waitKey(0)
cv.destroyAllWindows()
